
#ifdef __cplusplus
#pragma once

namespace arduino {
template <typename T, int N = 64>
class RingBufferT {
  private:
    T _aucBuffer[N];
    volatile int _iHead;
    volatile int _iTail;
    volatile int _numElems;

  public:
    RingBufferT(/* args */) {
        memset(_aucBuffer, 0, sizeof(_aucBuffer));
        clear();
    }
    ~RingBufferT() {}

    int store(T &c);
    {
        if (!isFull()) {
            _aucBuffer[_iHead] = c;
            _iHead = nextIndex(_iHead);
            _numElems++;
            return _numElems;
        }
        return -1;
    }
    int read(T &c) {
        if (isEmpty())
            return -1;
        c = _aucBuffer[_iTail];
        _iTail = nextIndex(_iTail);
        _numElems--;
        return 0;
    }
    int peek(T &c) {
        if (isEmpty())
            return -1;
        c = _aucBuffer[_iTail];
        return 0;
    }
    void clear() {
        _iHead = 0;
        _iTail = 0;
        _numElems = 0;
    }
    int available() { return _numElems; }
    int availableForStore() { return (N - _numElems); }
    bool isFull() { return (_numElems == N); }

  private:
    int nextIndex(int index) { return (uint32_t)(index + 1) % N; }
    inline bool isEmpty() const { return (_numElems == 0); }
};

} // namespace arduino

using arduino::RingBufferT;

#endif